home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CD ROM Paradise Collection 4
/
CD ROM Paradise Collection 4 1995 Nov.iso
/
system
/
ced_adds.zip
/
NEWCD.ASM
< prev
next >
Wrap
Assembly Source File
|
1995-10-30
|
11KB
|
394 lines
; CD Ver. 1.0
;
; This program replaces COMMAND.COM's CD. Basically, it works
; the same way. The current directory is changed to the pathname
; given as the only parameter. But, in case of an error, this new
; CD-command behaves differently: If the given parameter starts
; with '\' or '/', the current directory isn't changed and the
; program aborts with an error message.
; If the parameter only specifies part of a pathname and such a
; subdirectory doesn't exist in the current directory, the
; environement variable CDPATH is evaluated. This variable
; specifies a list of subdirectories, separated by ';', in which
; we have to look for the directory to change to.
; If we still aren't successfull in changing to that directory,
; it's time for an error message.
; The program, once loaded, stays in RAM and works as an
; extension of the command interpreter.
; The user may specify if the command CD without a parameter
; changes to the root directory or prints the pathname of the
; current directory.
;
; Copyright (C) 1987 by Urs Zurbuchen, Switzerland
;
; You may freely distribute this program unless you
; include the sources and don't touch this header.
; Commercial usage is prohibited.
;
; Requirements:
; This program requires that the command editor CED
; (by C.J. Dunford) is installed.
;
; Restrictions:
; The environement variable is evaluated when the program
; is loaded. Changes to the environement after the
; program is loaded into memory are NOT recognized.
; CDPATH may not be longer than CDLENGTH characters. You
; can change this value in the sources below.
;
; Usage: CD
; CD pathname
;
; Installation: NEWCD {r | p}
; r: change to root
; p: print current directory
; Default is r
;
; Assembly: MASM newcd;
; LINK newcd;
; EXE2BIN newcd newcd.com
;
; Author: Urs Zurbuchen
;
; Date: February 15, 1987
;
; Revisions:
; Date Who What
;
;----------------------------------------------------------------------
; adjust the following global according to the processor used
is_8088 equ 0 ; you won't have those fancy '286
; instructions if true
if is_8088
.8086
else
.286c ; this requires MASM 4.0
endif
; some global constants
cr equ 13 ; CarriageReturn
lf equ 10 ; LineFeed
space equ 32 ; (what do you guess :-)
tab equ 9 ; Tabulator
; definitions for the CED interface
ced equ 0ffh ; special DOS function for CED services
enqueue equ 0 ; Subfunction to CED: enqueue command
dequeue equ 1 ; Subfunction to CED: dequeue command
ced_dos equ 1 ; CED parameter: command at DOS prompt
ced_usr equ 2 ; CED parameter: command in user prg
; configurable constant
cdlength equ 255 ; max. string length of CDPATH
; here follows the program section
cseg segment para public 'code'
assume cs:cseg, ds:cseg, es:cseg
; initialization
org 100h
;-----------------------
; Installation procedure
;-----------------------
main proc far
jmp install ; go to installation
; datastructures
pwd: db 0 ; 0: change to root
; 1: print current dir
flag: db 0 ; 0: partial pathname
; 1: pathname starts with '\' or '/'
root: db '\',0 ; pathname for the root
path: db 67 dup (?) ; working-storage for pathnames
work: db 100 dup (?) ; working-storage (give it some reserves)
cdpath: db cdlength + 1 dup (?) ; CDPATH environement
; error messages
msg1$ db 'cd: directory not found', cr, lf, '$'
msg2$ db 'cd: HELP! HELP! Cannot change to root directory', cr, lf, '$'
msg3$ db 'cd: Cannot get current directory', cr, lf, '$'
msg4$ db 'cd: Too many parameters', cr, lf, '$'
;-----------------
; the CD procedure
;-----------------
newcd proc far
mov byte ptr [si],cr ; null out the users input
mov bp,dx
push ds ; save data segment
pop es
push cs ; set data segment context
pop ds
cd_1: mov al,byte ptr es:[bp] ; test for parameters
inc bp
cmp al,cr ; end of input reached ?
jz cd_noparam
cmp al,space ; leading spaces and tabs are ok
jz cd_1
cmp al,tab
jz cd_1
jmp cd_normal ; any other char inidicates pathname
cd_noparam:
cmp byte ptr [pwd],1 ; true, if we have to print current dir
jz cd_prcur
; change current dir to root
mov dx,offset root ; ds:dx points to pathname for root
mov ah,3bh ; change current directory
int 21h
jnc cd_nopara_1 ; avoid 'out of range'
jmp err_trouble ; you're in real trouble if this
; doesn't work
cd_nopara_1:
jmp cd_end
cd_prcur: ; print current directory
mov si,offset path ; ds:si points to storage for pathname
mov ah,19h ; get current drive
int 21h
add al,'A' ; change to human readable characters
mov ah,':'
mov word ptr [si],ax ; save drive name for print
inc si
inc si
mov byte ptr [si],'\' ; we don't get the first \ from DOS
inc si ; so we have to insert it
mov dl,0 ; we'd like the current drive
mov ah,47h ; get current directory
int 21h
jnc cd_prcur_1 ; avoid 'out of range'
jmp err_getcurrent ; can't imagine an error, but nobody's
; perfect
cd_prcur_1:
mov bx,1 ; file handle is standard output
mov dx,offset path ; start of text to print
xor cx,cx ; get length of string to print
mov bp,dx
cd_pr1: inc cx ; one char is always there ('\')
inc bp ; test next (!) character
cmp byte ptr ds:[bp],0 ; end of string is indicated by zero
jnz cd_pr1
mov ah,40h ; write to a file or device
int 21h ; print the string
jmp cd_end ; no test for error
cd_normal: ; test for additional parameters
mov di,offset path ; init pointers
mov cx,0
cmp al,'\' ; we have to know if the parameter
jz cd_mark ; starts with '\' or '/', or if it's
cmp al,'/' ; only a partial pathname
jnz cd_2
cd_mark: mov byte ptr [flag],1
cd_2: mov byte ptr [di],al ; save parameter
inc di
inc cx ; compute length of parameter in CX
mov al,byte ptr es:[bp] ; get next character
inc bp
cmp al,cr ; end of input reached ?
jz cd_cd
cmp al,space ; space and tab are delimiters
jz cd_3
cmp al,tab
jz cd_3
jmp cd_2 ; any other char belongs to pathname
cd_3: mov al,byte ptr es:[bp] ; test for additional parameters
inc bp
cmp al,cr ; end of input reached ?
jz cd_cd
cmp al,space ; space and tab are ok at the tail
jz cd_3
cmp al,tab
jz cd_3
jmp err_toomany ; any other char is bad
cd_cd: mov byte ptr [di], 0 ; change pathname to ASCIIZ
mov dx,offset path ; ds:dx points to pathname
mov ah,3bh ; change current directory
int 21h
jnc cd_end ; exit, if no error occurs
cmp byte ptr [flag],0 ; true if partial pathname
jnz err_invalidir ; full pathname leads to error
push ds ; update es. now, we can use the
pop es ; string commands
mov bp,offset cdpath ; ds:bp points to next path in CDPATH
mov si,offset path ; ds:si points to parameter
cd_path: ; try each entry in CDPATH as first part of the pathname
; we copy the next entry in CDPATH to the working-storage
; and append the actual parameter (the partial pathname)
cmp byte ptr ds:[bp],0 ; end of CDPATH is indicated by zero
jz err_invalidir ; I'm sorry, but I can't find that dir
mov di,offset work ; es:si points to working-storage
cd_copy:
mov al,byte ptr es:[bp] ; copy entry in CDPATH
cmp al,0 ; end reached?
jz cd_p1
cmp al,';' ; end is indicated by zero or ';'
jz cd_p1
stosb
inc bp
jmp cd_copy
cd_p1: inc bp ; adjust pointer
mov byte ptr [di],'\' ; insert delimiter
inc di
push cx
push si
repnz movsb ; append parameter
pop si
pop cx
mov byte ptr [di],0 ; mark end
mov dx,offset work ; ds:dx points to the pathname
mov ah,3bh
int 21h
jc cd_path ; repeat if still no valid directory
cd_end: mov byte ptr [flag],0 ; reset flag
ret ; exit to CED
newcd endp
;--------------
; error handler
;--------------
error proc near
err_trouble: ; you're in real trouble if we can't change to the root
; I hope you have a real good 'disk doctor'
mov dx,offset msg2$
jmp err_common
err_getcurrent: ; can't get the current directory's pathname
; This isn't much better as the above
mov dx,offset msg3$
jmp err_common
err_toomany: ; you specified too many parameters (only one allowed)
mov dx,offset msg4$
jmp err_common
err_invalidir: ; you specified an invalid pathname
mov dx,offset msg1$
err_common: ; common point for error output
mov ah,9 ; print string
int 21h
jmp cd_end
error endp
;-------------------------------------------------------------------
; This is the installation routine. It queues the two commands above
; into the CED command editor. It terminates but leaves the command
; routines resident.
;-------------------------------------------------------------------
install:
push cs
pop ds
push ds
pop es
mov ah,ced ; request CED service from DOS
mov al,enqueue ; enqueue a new command
mov bl,ced_dos ; CD is only active at DOS prompt
mov si,offset cd$ ; pointer to command name
mov di,offset newcd ; pointer to service routine
int 21h
jnc inst_ok ; no error: exit
mov dx, offset msg_inst1$ ; only error 8 is possible here
inst_err:
mov ah, 9 ; print string
int 21h
int 20h ; exit without staying resident
inst_ok:
push ds
mov si,2ch ; ds:si points to environement
mov ds,word ptr [si]
mov si,0
mov di,offset cdpath ; es:di points to space for CDPATH string
mov cx,0
inst_search: ; search for environement variable CDPATH
cmp byte ptr [si],0 ; test for end of environement string
jz inst_end
mov bp,offset cdpath$ ; name of environement variable
inst_loop: ; compare an environement entry with
lodsb ; the variable name
inc bp
cmp al,byte ptr es:[bp-1]
jnz inst_skip
cmp al,'='
jnz inst_loop
jmp inst_copy
inst_skip: ; skip to next entry
inc si
cmp byte ptr [si-1],0
jnz inst_skip
jmp inst_search
inst_copy: ; copy definition
lodsb ; get a char
stosb
inc cx ; max. string length is cdlength
cmp cx,cdlength
jnc inst_end
or al,al ; end reached? (marked by zero)
jnz inst_copy ; no: copy more
inst_end:
mov byte ptr [di],0 ; mark end of CDPATH
pop ds
mov cx,0
mov bp,[80h]
mov cl,byte ptr es:[bp] ; any parameter given?
jcxz inst_tsr ; no: exit without changing the flag
inst_para:
mov al,es:[bp+1] ; leading spaces and tabs are ok
inc bp
cmp al,space
jz inst_para
cmp al,tab
jz inst_para
or al,20h ; change into lower case
cmp al,'p' ; p means 'print current dir'
jz inst_print
loopnz inst_para
jmp inst_tsr ; don't change flag: 'go to root'
inst_print:
mov byte ptr [pwd],1 ; set flag to 'print current dir'
inst_tsr:
mov dx,offset install ; ok: terminate/resident
int 27h
main endp
; messages for installation procedure
msg_inst1$ db 'install cd: CED command list full', cr, lf, '$'
; command name
cd$ db 'cd', cr
; environement variable name
cdpath$ db 'CDPATH='
cseg ends
end main